package revisaosistematica;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 *
 * @author claudiane
 */
public class Avaliacao {
    
    //Obtem a precisao e revocao para cada consulta
    public static List<Registro> getPrecisaoRevocacao(Set<Integer> hashDocRel, List<Registro> listaRank, List<Registro> listaMedia){
        
        //preenche a lista de com o primeiro valor de 10 em 10 até 100 e o segundo valor com 0
        List<Registro> listPrecRev = new ArrayList<Registro>();
        for (int i=0;i<=100;i=i+10){
           
            listPrecRev.add(new Registro(i,0,0,""));
        }
        
        //Numero de documentos recuperados pelo sistema que são relevantes
        int numDocRecuperadosRelevantes = 0;
        //Numero de documentos recuperados pelo sistema em geral (inclui relevantes e não relevantes)
        int numDocRecuperados = 1;
        
        //Quantidade de documentos relevantes
        int numDocRelevantes = hashDocRel.size();
        //System.out.println(" numDocRelevantes " +numDocRelevantes);
        
        int nivel = 10;
        
        //Percorre a lista de docs e ranks retornados pelo sistema
        for (int i=0;i<listaRank.size();i++){
            
            //Obtendo o numero de documentos por nível
            int numDocPorNivel = (int) Math.ceil((float)(numDocRelevantes * nivel)/(float)100);
            
            //verifica se o doc encontrado esta presente na hash de resultado da colecao (Faz a interceção)
            if(hashDocRel.contains(listaRank.get(i).getIndice())){
                
                //incrementa o numero de documento recuperados relevantes
                numDocRecuperadosRelevantes++; 
                
                //verifica se o numero de documentos recuperados relevantes é igual ao nivel calculado para o nível
                if (numDocRecuperadosRelevantes == numDocPorNivel){
                    
                    //calcula a precisão a cada nivel (precisao = numero de documentos recuperados que sao relevantes)
                    float precisao = ((float)numDocRecuperadosRelevantes/(float)numDocRecuperados) * 100;

                    // Posicao recebe o valor do nivel dividido por 10 para ter a posicao de 0 a 10 
                    int posicao = (int) nivel / 10;

                    if (precisao!=0){

                        //atualiza o valor da precisao que era = 0 para o valor calculado
                        listPrecRev.get(posicao).setValor(precisao);

                        //System.out.println("\tPosicao: "+posicao + "\tRevocação: "+nivel+ "\tPrecisao: "+ precisao);

                        //realiza a interpolaçao dos valores da precisao
                        for (int pos = posicao - 1; pos >= 0; pos--){

                            //verifica se o valor da precisao na posicao anterior é menor do que o valor atual da precisao
                            //se for menor atualiza os valores anteriores
                            if (listPrecRev.get(pos).getValor() < precisao){

                                listPrecRev.get(pos).setValor(precisao);

                            } else {

                                break;
                            }
                        }

                    }

                    //incrementa o nível para calcular a precisao para o proximo
                    nivel = nivel + 10;
                }
            }
          
            numDocRecuperados++;
            
        }
        //System.out.println("Calculos da Precisão e Revocação");
        for (int i=0;i<listPrecRev.size();i++){
            
            listaMedia.get(i).setValor(listaMedia.get(i).getValor() + (listPrecRev.get(i).getValor()/100) );
            
           // System.out.println("\tRevocacao: "+listPrecRev.get(i).getIndice()+ "\tPrecisao: "+ listPrecRev.get(i).getValor());
        }
        
        return listaMedia;
    }
}
